﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Globalization;
using System.Threading;
using System.Data.SqlClient;
using System.Data;
using Microsoft.SqlServer.Types;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace GeometryViewerUI
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        SqlConnection conn;
        public ObservableCollection<StringBoolBoolClass> GraphList { get; set; }

        public MainWindow()
        {
            InitializeComponent();

            GraphList = new ObservableCollection<StringBoolBoolClass>();
            /*GraphList.Add(new StringBoolBoolClass { id = 2, TheText = "2" });
            GraphList.Add(new StringBoolBoolClass { id = 1, TheText = "1" });*/
            this.DataContext = this;
            if (Thread.CurrentThread.CurrentCulture.Name == "ru-RU")
            {
                RussianLocal.IsChecked = true;
                EnglishLocal.IsChecked = false;
            }
        }

        private void ConnectMenuItem_Click(object sender, RoutedEventArgs e)
        {
            ConnectionDialog dlg = new ConnectionDialog();
            bool? result = dlg.ShowDialog();
            if (result.HasValue && result.Value)
            {
                this.conn = dlg.Connection;
                gvcDownLeft.conn = dlg.Connection;
                gvcUpperLeft.conn = dlg.Connection;
                gvcDownRight.conn = dlg.Connection;
                gvcUpperRight.conn = dlg.Connection;

                /*btnConnect.IsEnabled = false;
                btnDisconnect.IsEnabled = true;
                btnAddSQL.IsEnabled = true;

                stConnectionStatus.Text = string.Format("Connected - {0}", this.conn.Database);*/
            }
        }

        private void ExitMenuItem_Click(object sender, RoutedEventArgs e)
        {
            Application.Current.Shutdown();
        }

        private void ChangeLocal_Click(object sender, RoutedEventArgs e)
        {
            string a = ((MenuItem)sender).Name;
            if (a == "EnglishLocal")
                RussianLocal.IsChecked = !RussianLocal.IsChecked;
            else
                EnglishLocal.IsChecked = !EnglishLocal.IsChecked;
            if (RussianLocal.IsChecked)
                ChangeLocalization("ru-RU");
            if (EnglishLocal.IsChecked)
                ChangeLocalization("en-US");
        }
        private void ChangeLocalization(string localizationName)
        {
            // Change thread localization
            Thread.CurrentThread.CurrentUICulture = new CultureInfo(localizationName);
            Thread.CurrentThread.CurrentCulture = new CultureInfo(localizationName);
            Properties.Resources.Culture = new CultureInfo(localizationName);
            // Refresh localizable values

            FileMenuItem.Header = Properties.Resources.MenuItemFile;
            this.Title = Properties.Resources.PageTitle;
            ConnectMenuItem.Header = Properties.Resources.ConnectMenuItem;
            ExitMenuItem.Header = Properties.Resources.ExitMenuItem;
            EnglishLocal.Header = Properties.Resources.EnglishLocal;
            RussianLocal.Header = Properties.Resources.RussianLocal;
            LocalMenuItem.Header = Properties.Resources.LocalMenuItem;
            GraphsMenuItem.Header = Properties.Resources.MenuItemGraphs;
            EditListMenuItem.Header = Properties.Resources.MenuItemEditList;
            SortListMenuItem.Header = Properties.Resources.MenuItemSortList;
            SortListByIdMenuItem.Header = Properties.Resources.MenuItemSortListById;
            SortListByNameMenuItem.Header = Properties.Resources.MenuItemSortListByName;
            SortListBySimilarityMenuItem.Header = Properties.Resources.MenuItemSortListBySimilarity;

            gvcUpperLeft.ZoomLevelXText = Properties.Resources.ZoomLevelX;
            gvcUpperLeft.ZoomLevelYText = Properties.Resources.ZoomLevelY;
            gvcUpperLeft.ResetSizeButtonText = Properties.Resources.ResetSizeButtonText;

            gvcUpperRight.ZoomLevelXText = Properties.Resources.ZoomLevelX;
            gvcUpperRight.ZoomLevelYText = Properties.Resources.ZoomLevelY;
            gvcUpperRight.ResetSizeButtonText = Properties.Resources.ResetSizeButtonText;
            gvcDownLeft.ZoomLevelXText = Properties.Resources.ZoomLevelX;
            gvcDownLeft.ZoomLevelYText = Properties.Resources.ZoomLevelY;
            gvcDownLeft.ResetSizeButtonText = Properties.Resources.ResetSizeButtonText;
            gvcDownRight.ZoomLevelXText = Properties.Resources.ZoomLevelX;
            gvcDownRight.ZoomLevelYText = Properties.Resources.ZoomLevelY;
            gvcDownRight.ResetSizeButtonText = Properties.Resources.ResetSizeButtonText;
            GraphListDataGrid.Columns[0].Header = Properties.Resources.GraphName;
            GraphListDataGrid.Columns[1].Header = Properties.Resources.LeftPanel;
            GraphListDataGrid.Columns[2].Header = Properties.Resources.RightPanel;
        }

        private void FirstPanelCheckBox_Click(object sender, RoutedEventArgs e)
        {

            StringBoolBoolClass a = (StringBoolBoolClass)GraphListDataGrid.SelectedItems[0];
            foreach (StringBoolBoolClass sbbc in GraphList)
            {
                if (sbbc.id != a.id)
                {
                    sbbc.IsOnFirstPanel = false;
                }
                else
                {
                    sbbc.IsOnFirstPanel = true;
                    gvcUpperLeft.ShowGraph(sbbc.id);
                }
            }
            ((CheckBox)sender).IsChecked = true;

        }
        private void SecondPanelCheckBox_Click(object sender, RoutedEventArgs e)
        {
            StringBoolBoolClass a = (StringBoolBoolClass)GraphListDataGrid.SelectedItems[0];
            foreach (StringBoolBoolClass sbbc in GraphList)
            {
                if (sbbc.id != a.id)
                {
                    sbbc.IsOnSecondPanel = false;
                }
                else
                {
                    sbbc.IsOnSecondPanel = true;
                    gvcUpperRight.ShowGraph(sbbc.id);
                }
            }
            ((CheckBox)sender).IsChecked = true;
        }
        private void EditListMenuItem_Click(object sender, RoutedEventArgs e)
        {
            GraphLIstEditDialog dlg = new GraphLIstEditDialog(conn);
            bool? result = dlg.ShowDialog();
            if (result.HasValue && result.Value)
            {
                GraphList.Clear();
                foreach(DatabaseEntityWrapper dew in dlg.databaseList)
                    if (dew.Include)
                        GraphList.Add(new StringBoolBoolClass{id=dew.id, TheText = dew.FileName });
            }
            
        }
        private void SortListByIdMenuItem_Click(object sender, RoutedEventArgs e)
        {
            var sorted = GraphList.OrderBy(x => x.id);
            List<StringBoolBoolClass> tmpList = new List<StringBoolBoolClass>(sorted);
            GraphList.Clear();
            foreach (StringBoolBoolClass sbbc in tmpList)
            {
                GraphList.Add(new StringBoolBoolClass(sbbc));
            }
        }
        private void SortListByNameMenuItem_Click(object sender, RoutedEventArgs e)
        {
            var sorted = GraphList.OrderBy(x => x.TheText);
            List<StringBoolBoolClass> tmpList = new List<StringBoolBoolClass>(sorted);
            GraphList.Clear();
            foreach (StringBoolBoolClass sbbc in tmpList)
            {
                GraphList.Add(new StringBoolBoolClass(sbbc));
            }
        }
        private void SortListBySimilarityMenuItem_Click(object sender, RoutedEventArgs e)
        {
            double indent = 0;
            SimilarityDeviationDialog dlg = new SimilarityDeviationDialog();
            bool? result = dlg.ShowDialog();
            if (result.HasValue && result.Value)
            {
                indent = dlg.indent;
            }
            int id = 0;
            foreach (StringBoolBoolClass sbbc in GraphList)
            {
                if (sbbc.IsOnFirstPanel)
                    id = sbbc.id;
            }

            List<int> idList = new List<int>();
            foreach (StringBoolBoolClass sbbc in GraphList)
            {
                idList.Add(sbbc.id);
            }
            string idListString = string.Join(",", idList.Select(n => n.ToString()).ToArray());

            List<KeyValuePair<int, double>> degrees = new List<KeyValuePair<int, double>>();
            
            string similarityDegreeString = indent.ToString().Replace(",", ".");
            conn.Open();
            SqlCommand cmd = conn.CreateCommand();
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = "SELECT [Graphs].[dbo].[SimilarityDegree] (" +
                "(select graph from Graphs where id = " + id.ToString() + "), graph, " + similarityDegreeString + ") as degree, id as GraphId" +
                " from Graphs where id in (" + idListString + ");";
            using (SqlDataReader rdr = cmd.ExecuteReader())
            {
                rdr.Read();
                do
                {
                    degrees.Add(new KeyValuePair<int,double>(Convert.ToInt32(rdr[1]), Convert.ToDouble(rdr[0])));
                } while (rdr.Read());
            }
            conn.Close();
            var sorted = degrees.OrderByDescending(x => x.Value);
            List<KeyValuePair<int, double>> degreesSorted = new List<KeyValuePair<int, double>>(sorted);
            List<StringBoolBoolClass> tmpList = new List<StringBoolBoolClass>();
            foreach (KeyValuePair<int, double> kvp in degreesSorted)
            {
                StringBoolBoolClass sbbc = null;
                foreach (StringBoolBoolClass sb in GraphList)
                    if (sb.id == kvp.Key)
                        sbbc = new StringBoolBoolClass(sb);
                tmpList.Add(sbbc);
            }
            GraphList.Clear();
            foreach (StringBoolBoolClass sbbc in tmpList)
            {
                GraphList.Add(new StringBoolBoolClass(sbbc));
            }


        }

        private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            string selectedItemName = ((ComboBoxItem)((ComboBox)sender).SelectedItem).Name;
            if (indentLabel != null)
            {
                if (selectedItemName == "SimilarityDegreePairProcessingStyle")
                {
                    indentLabel.Visibility = System.Windows.Visibility.Visible;
                    indentValueTextBox.Visibility = System.Windows.Visibility.Visible;
                    SimilarityCoefficienStackPanel.Visibility = System.Windows.Visibility.Visible;
                }
                else
                {
                    indentLabel.Visibility = System.Windows.Visibility.Collapsed;
                    indentValueTextBox.Visibility = System.Windows.Visibility.Collapsed;
                    SimilarityCoefficienStackPanel.Visibility = System.Windows.Visibility.Collapsed;
                }
            }
        }

        private void RecalculatePairProcessing_Click(object sender, RoutedEventArgs e)
        {
            int id1 = 0;
            int id2 = 0;
            foreach (StringBoolBoolClass sbbc in GraphList)
            {
                if (sbbc.IsOnFirstPanel)
                    id1 = sbbc.id;
                if (sbbc.IsOnSecondPanel)
                    id2 = sbbc.id;
            }
            string processing = "";
            switch (((ComboBoxItem)PairProcessingStyle.SelectedItem).Name)
            {
                case "AverageGraphPairProcessingStyle":
                    processing = "average";
                    break;
                case "BottomBorderPairProcessingStyle":
                    processing = "BottomBorder";
                    break;
                case "TopBorderPairProcessingStyle":
                    processing = "TopBorder";
                    break;
                case "OuterBorderPairProcessingStyle":
                    processing = "OuterBorder";
                    break;
                case "SimilarityDegreePairProcessingStyle":
                    processing = "similarityDegree";
                    break;
                default:
                    break;
            }

            double res = gvcDownLeft.PairProcessind(id1, id2, processing, Convert.ToDouble(indentValueTextBox.Text.Replace(".", ",")));
            if (processing == "similarityDegree")
                SimilarityCoefficienTextBox.Text = res.ToString();
        }

        private void RecalculateGroupProcessing_Click(object sender, RoutedEventArgs e)
        {
            List<int> idList = new List<int>();
            foreach (StringBoolBoolClass sbbc in GraphList)
            {
                idList.Add(sbbc.id);
            }

            string processing = "";
            switch (((ComboBoxItem)GroupProcessingStyle.SelectedItem).Name)
            {
                case "AverageGraphGroupProcessingStyle":
                    processing = "average";
                    break;
                case "BottomBorderGroupProcessingStyle":
                    processing = "BottomBorder";
                    break;
                case "TopBorderGroupProcessingStyle":
                    processing = "TopBorder";
                    break;
                case "OuterBorderGroupProcessingStyle":
                    processing = "OuterBorder";
                    break;
                case "SimilarityDegreeGroupProcessingStyle":
                    processing = "similarityDegree";
                    break;
                default:
                    break;
            }
            gvcDownRight.GroupProcessind(idList, processing);
        }

    }
    public class StringBoolBoolClass : INotifyPropertyChanged
    {
        private int idValue = 0;
        private string TheTextValue = "";
        private bool IsOnFirstPanelValue = false;
        private bool IsOnSecondPanelValue = false;

        public event PropertyChangedEventHandler PropertyChanged;
        public StringBoolBoolClass()
        {
        }
        public StringBoolBoolClass(StringBoolBoolClass a)
        {
            this.id = a.id;
            this.TheText = a.TheText;
            this.IsOnFirstPanel = a.IsOnFirstPanel;
            this.IsOnSecondPanel = a.IsOnSecondPanel;

        }
        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
        public int id {
            get
            {
                return this.idValue;
            }
            set
            {
                if (value != this.idValue)
                {
                    this.idValue = value;
                    NotifyPropertyChanged("id");
                }
            }
        }
        public string TheText
        {
            get
            {
                return this.TheTextValue;
            }
            set
            {
                if (value != this.TheTextValue)
                {
                    this.TheTextValue = value;
                    NotifyPropertyChanged("TheText");
                }
            }
        }
        public bool IsOnFirstPanel
        {
            get
            {
                return this.IsOnFirstPanelValue;
            }
            set
            {
                if (value != this.IsOnFirstPanelValue)
                {
                    this.IsOnFirstPanelValue = value;
                    NotifyPropertyChanged("IsOnFirstPanel");
                }
            }
        }
        public bool IsOnSecondPanel
        {
            get
            {
                return this.IsOnSecondPanelValue;
            }
            set
            {
                if (value != this.IsOnSecondPanelValue)
                {
                    this.IsOnSecondPanelValue = value;
                    NotifyPropertyChanged("IsOnSecondPanel");
                }
            }
        }
    }
}
